package com.techgene.kanban.controller;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;

import com.techgene.kanban.domain.RequestParamUser;
import com.techgene.kanban.domain.User;
import com.techgene.kanban.exception.KBServiceException;
import com.techgene.kanban.service.LoginService;
import com.techgene.kanban.util.AppConstants;
import com.techgene.kanban.util.JsonUtil;




/**
 * Login and logoff handlers
 * 
 * @author Techgene
 * 
 */
@Controller
public class LoginLogoffController {

	private Logger logger = LoggerFactory.getLogger(LoginLogoffController.class);

	@Autowired
	LoginService loginService;




	/**
	 * Shows the login page.
	 * @param user  Model attribute object to save the form data
	 * @param model  ModelMap
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public ModelAndView showLoginPage(ModelMap model, HttpServletRequest request) {

		logger.debug(">> showLoginPage ");
		ModelAndView returnView = null;

		/*
		 * if user is not present then create a new user object and set into the
		 * model else if user is present then redirect the user to there
		 * corresponding pages if /login is somehow hit.
		 */
		if (request.getSession().getAttribute(AppConstants.SESSION_ATTR_USER_NAME) != null && request.getSession().getAttribute(AppConstants.SESSION_ATTR_USER_ROLE) != null) {

			if (((String) request.getSession().getAttribute(AppConstants.SESSION_ATTR_USER_ROLE)).equalsIgnoreCase("admin")) {

				returnView = new ModelAndView(new RedirectView("admin/login"));

			}
			if (((String) request.getSession().getAttribute(AppConstants.SESSION_ATTR_USER_ROLE)).equalsIgnoreCase("manager")) {

				returnView = new ModelAndView(AppConstants.MANAGER_PAGE);

			}
			if (((String) request.getSession().getAttribute(AppConstants.SESSION_ATTR_USER_ROLE)).equalsIgnoreCase("developer")) {

				returnView = new ModelAndView(AppConstants.DEVELOPER_PAGE);

			}

		} else {

			model.addAttribute("User", new RequestParamUser());
			returnView = new ModelAndView(AppConstants.LOGIN_PAGE,"statussMsg",request.getParameter("statussMsg"));
		}

		logger.debug("<< showLoginPage [model = {}]", model);
		return returnView;
	}

	
	
	
/**
 * It shows the admin home page.
 * @return
 */

	@RequestMapping(value="/admin/login")
	public ModelAndView adminHomePage()
	{
		logger.debug(">>adminHomepage");
		logger.debug("<<adminHomepage");
		return new ModelAndView(AppConstants.ADMIN_PAGE);
		
	}
	
	
	
	

	/**
	 * Login submit handler
	 * @param user
	 * @param request
	 * @param flashData
	 * @param model  ModelMap
	 * @param result
	 * @return
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public ModelAndView submitLoginPage(@ModelAttribute("requestUser") RequestParamUser requestParamUser, HttpServletRequest request, RedirectAttributes flashData,ModelMap model) {

		logger.debug("<< submitLoginPage");
		ModelAndView returnView = null;
		User user=new User();
		user.setPassword(requestParamUser.getPassword());
		user.setUsername(requestParamUser.getUsername());
		try {

			/*
			 * calling validate User method for User is valid or not. if the
			 * user is not valid then user = null else user object will hold the
			 * user details
			 */
			user = loginService.validateUser(user.getUsername(),user.getPassword());
			logger.debug("user = {} ", JsonUtil.prettyPrintBean(user));
			if (user.getRole() == null) {

				model.addAttribute("User", new User());
				flashData.addFlashAttribute("statusMsg",AppConstants.USER_LOGIN_FAILURE_MESSAGE);
				returnView = new ModelAndView(new RedirectView(AppConstants.LOGIN_PAGE));

			} 
			else {

				if (user.getRole().equalsIgnoreCase("admin")) {

					request.getSession().setAttribute(AppConstants.SESSION_ATTR_USER_NAME,user.getUsername());
					request.getSession().setAttribute(AppConstants.SESSION_ATTR_USER_ROLE,user.getRole());
					returnView = new ModelAndView(new RedirectView("admin/login"));
				}

				else if (user.getRole().equalsIgnoreCase("manager")) {

					request.getSession().setAttribute(AppConstants.SESSION_ATTR_USER_NAME,user.getUsername());
					returnView = new ModelAndView(AppConstants.MANAGER_PAGE);
				}

				else if (user.getRole().equalsIgnoreCase("developer")) {

					request.getSession().setAttribute(AppConstants.SESSION_ATTR_USER_NAME,user.getUsername());
					returnView = new ModelAndView(AppConstants.DEVELOPER_PAGE);
				}

			}

		} catch (KBServiceException e) {

			logger.error(e.getMessage(), e);
			flashData.addFlashAttribute("errorMsg", e.getMessage());
			returnView = new ModelAndView(new RedirectView(AppConstants.COMMON_ERROR_PAGE));

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			flashData.addFlashAttribute("errorMsg", e.getMessage());
			returnView = new ModelAndView(new RedirectView(AppConstants.COMMON_ERROR_PAGE));

		}

		logger.debug(">> submitLoginPage [returnView = {}] ", returnView);
		return returnView;
	}





	/**
	 * Upon logoff action, this handler is called.
	 * 
	 * @param user
	 * @param model
	 * @param request
	 * @param session
	 * @param falshData
	 * @return
	 */
	@RequestMapping(value = {"/logout","/admin/logout"},method = RequestMethod.GET)
	public RedirectView logOut(HttpServletRequest request,RedirectAttributes falshData) {

		logger.debug(" >> logOut ");

		/*
		 * if user is found in the session then user object is removed from
		 * session scope and then session is invalidated
		 */
		if (request.getSession().getAttribute("user") != null) {

			request.getSession().removeAttribute("user");
		}

		request.getSession().invalidate();
		falshData.addFlashAttribute("statusMsg",AppConstants.USER_LOGOUT);
		logger.debug("<< logOut ");
		return new RedirectView(AppConstants.LOGIN_PAGE);

	}




	/**
	 * calling error jsp page
	 * 
	 * @return
	 */
	@RequestMapping(value = {"/error","/admin/error"},method = RequestMethod.GET)
	public ModelAndView showErrorPage(@RequestParam String errorMsg) {

		logger.debug(" >> showErrorPage ");
		logger.debug(" << showErrorPage ");
		return new ModelAndView(AppConstants.COMMON_ERROR_PAGE,"errorMsg",errorMsg);
	}

	
	
	
	/**
	 * going back to admin page
	 * @return
	 */
	@RequestMapping(value = {"/back","/admin/back"},method = RequestMethod.GET)
	public ModelAndView backPage() {

		logger.debug(" >> backPage ");
		logger.debug(" << backPage ");
		return new ModelAndView(AppConstants.ADMIN_PAGE);
	}
}
